#include <unistd.h>
#include <zookeeper.h>
#include <zookeeper_log.h>
#include <iostream>
#include <pthread.h>

using namespace std;

//g++ test5.cpp  -I ../src/c/include/ -I ../src/c/generated/ -L/home/sxz/sxz/zookeeper-3.4.7/src/c/.libs/ -lzookeeper_mt -lpthread


zhandle_t* zkhandle = NULL;
const char* host = "127.0.0.1:2181";
int timeout = 20000;

void InitWatch(zhandle_t* zh, int type, int state, const char* path, void* watcher) {
        if (type == ZOO_SESSION_EVENT) {
                if (state == ZOO_CONNECTED_STATE) {
                        cout << "build connection ok" << endl;
                } else if (state == ZOO_EXPIRED_SESSION_STATE) {
                        cout << "connection disconnect" << endl;
                        zkhandle = zookeeper_init(host, InitWatch, timeout, 0, const_cast<char*>("TODO"), 0);
                }
        }
}

void CreateWatch(int rc, const char *name, const void *data) {
        if (rc == ZNODEEXISTS || rc == ZOK) {
                if (rc == ZOK) {
                        cout << "registry ok" << endl;
                } else {
                        cout << "node exist" << endl;
                }
        } else {
                cout << "registry error" << endl;
        }
}


//int zoo_wget(zhandle_t *zh, const char *path, watcher_fn watcher, void* watcherCtx, char *buffer, int* buffer_len, struct Stat *stat)
void ChangeWatch(zhandle_t* zh,int type, int state,const char *path,void *watcherCtx);
void * Wget(void *arg)
{
        zhandle_t *zh=(zhandle_t *)arg;
        char buffer[64]={0};
        int buffer_len=64;
        const char *path= "/sxz";
        int ret= zoo_wget(zh, path,ChangeWatch,NULL,buffer,&buffer_len, NULL);
        if (ret)    {
                cout<<"Wget error\n";
        }
        cout<<buffer<<"Wget ...."<<endl;
        while(1);
}

static const char* state2String(int state){
        if (state == 0)
                return "CLOSED_STATE";
        if (state == ZOO_CONNECTING_STATE)
                return "CONNECTING_STATE";
        if (state == ZOO_ASSOCIATING_STATE)
                return "ASSOCIATING_STATE";
        if (state == ZOO_CONNECTED_STATE)
                return "CONNECTED_STATE";
        if (state == ZOO_EXPIRED_SESSION_STATE)
                return "EXPIRED_SESSION_STATE";
        if (state == ZOO_AUTH_FAILED_STATE)
                return "AUTH_FAILED_STATE";

        return "INVALID_STATE";
}

static const char* type2String(int state){
        if (state == ZOO_CREATED_EVENT)
                return "CREATED_EVENT";
        if (state == ZOO_DELETED_EVENT)
                return "DELETED_EVENT";
        if (state == ZOO_CHANGED_EVENT)
                return "CHANGED_EVENT";
        if (state == ZOO_CHILD_EVENT)
                return "CHILD_EVENT";
        if (state == ZOO_SESSION_EVENT)
                return "SESSION_EVENT";
        if (state == ZOO_NOTWATCHING_EVENT)
                return "NOTWATCHING_EVENT";

        return "UNKNOWN_EVENT_TYPE";
}

//typedef void (*watcher_fn)(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx);
void ChangeWatch(zhandle_t* zh,int type, int state,const char *path,void *watcherCtx)
{
        cout<<type2String(type)<<endl;
        cout<<state2String(state)<<endl;
        cout<<path<<endl;
        zoo_wexists(zh,path,ChangeWatch,NULL,NULL); // 监听匿名用户路径节点,一定要再次设置监听，不然只会监听一次
}


int main(int argc, char* argv[]) {
        zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
        zhandle_t* zkhandle = NULL;
        zkhandle = zookeeper_init(host, InitWatch, timeout, 0, const_cast<char*>("TODO"), 0);
        if (NULL == zkhandle) {
                cout << "zookeeper init error" << endl;
                return 0;
        }
        /* while (1) {
           int ret = zoo_acreate(zkhandle, "/index", "", 8, &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL|ZOO_SEQUENCE, CreateWatch, "create");
           if (ret) {
           cout << "zoo_acreate error :" << ret << endl;
           }
           sleep(5);
           }
           */
        pthread_t thread;
        int ret=pthread_create(&thread,NULL,Wget,(void *)zkhandle) ; //监听线程
        //Wget(zkhandle);
        //while(1);
        pthread_join(thread,NULL);
        zookeeper_close(zkhandle);

        return 0;
}
